#ifndef DECODER_H_
#define DECODER_H_
#include <iostream>
#include <string>
#include <map>
#include "../messages/register.h"
#include "../messages/file_not_found.h"
#include "../messages/files_list.h"
#include "../messages/get_file.h"
#include "../messages/get_files_list.h"
#include "../messages/logging_error.h"
#include "../messages/logging_ok.h"
#include "../messages/message.h"
#include "../messages/no_files.h"
#include "../messages/notify.h"
#include "../messages/put_error.h"
#include "../messages/put_file.h"
#include "../messages/put_ok.h"
#include "../messages/unregister.h"
#include "../messages/max_login_tries.h"
#include "../messages/delete.h"
#include "../messages/delete_ok.h"
#include "../messages/delete_error.h"
#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <sstream>
#include <stdlib.h>
#include <stdint.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include "Decoder.h"
#define AMOUNT_BYTES_LONG 4
#define AMOUNT_BYTES_IDENTIFY 1
#define MAX_TAM_CAMPO 100
#define BYTESMD5 32
/***IDS****
 0:REGISTER
 1:LOGGING-OK
 2:LOGGING-ERROR
 3:GET-FILES-LIST
 4:NO-FILES
 5:FILES-LIST
 6:GET-FILE
 7:FILE-NOT-FOUND
 8:DATA (DEPRECATED)
 9:PUT-FILE
 10:PUT-OK
 11:PUT-ERROR
 12:NOTIFY
 13:UNREGISTER
 14: MAX-LOGIN-TRIES
 15: DELETE-FILE
 16: DELETE-OK
 17: DELETE-ERROR

 ***********/


class Decoder {
public:
	typedef std::string File_Name; // Nombre de archivo
	typedef std::string Hash; // Hash
	typedef std::map<File_Name, Hash> Map; // Map que tiene como clave el nombre de archivo, y como valor su Hash

public:
	/* Constructor */
	Decoder();

	/* Parsea los primeros bytes para identificar que tipo de mensaje es, y luego
	 * llama al metodo que se encargara de parsear los campos*/
	Message* parser(std::string& receive);

	/* Arma el map de nombres de archivos con sus respectivos hashes*/
	FilesList* receive_list(std::string& receive);

	/* Parsea el nombre de usuario, y su contraseña */
    Register* register_to_server(std::string& receive);

	/* Parsea el nombre del archivo*/
    std::string get_file_name(std::string& receive);

    /* Devuelve un msg con el nombre del archivo solicitado por el cliente*/
    GetFile* get_file(std::string& receive);

    /* Enviado por el servidor en caso que el archivo solicitado no exista */
    FileNotFound* file_not_found(std::string& receive);

	/* Transferencia del archivo desde el cliente al servidor */
	PutFile* put(std::string& receive);

	/* Server avisa que el archivo fue recibido exitosamente*/
	PutOk* putOk(std::string& receive);

	/* Server avisa que el archivo no fue recibido, o fue recibido erroneamente */
	PutError* putError(std::string& receive);

	/* Notificacion de cambio, borrado o agregado de algun archivo*/
	Notify* notify(std::string& receive);

	/* Parsea y obtiene el nombre del archivo a eliminar*/
	Delete* delete_file(std::string& receive);

	/* Parsea y obtiene el nombre del archivo que se elimino correctamente*/
	DeleteOk* deleteOk(std::string& receive);

	/* Parsea y obtiene el nombre del archivo que el server por alguna razon no pudo eliminar*/
	DeleteError* deleteError(std::string& receive);

	/* Devuelve id del mensaje */
	int get_id_msg();

	/* Destructor*/
	virtual ~Decoder();

private:
	int id_msg; //id del mensaje, segun los protocolos elegidos
};

#endif /* DECODER_H_ */

